How CSS content-visibility Works and How It Can Improve Rendering Performance

ویژگی CSS content-visibility چگونه کار می‌کند و چگونه می‌تواند عملکرد رندرینگ را بهبود بخشد

چه اتفاقی می‌افتد وقتی یک صفحه دارای ۱۵۰ کارت پر از محتوا است، اما کاربر فقط می‌تواند چند تای اول را ببیند؟ ممکن است انتظار داشته باشید مرورگر فقط نگران مواردی باشد که در حال حاضر قابل مشاهده هستند. اما این دقیقاً همان چیزی نیست که ها

چه اتفاقی می‌افتد وقتی یک صفحه دارای ۱۵۰ کارت پر از محتوا است، اما کاربر فقط می‌تواند چند کارت اول را ببیند؟

شما ممکن است انتظار داشته باشید که مرورگر فقط نگران چیزهایی باشد که در حال حاضر قابل مشاهده هستند. اما این دقیقاً همان چیزی نیست که اتفاق می‌افتد.

محتوا می‌تواند هزاران پیکسل پایین‌تر از محدوده دید (viewport) باشد، و مرورگر ممکن است همچنان کارهای مربوط به رندرینگ را برای آن انجام دهد.

بنابراین می‌خواستم چیزی را امتحان کنم. چه می‌شود اگر بتوانیم اساساً به مرورگر بگوییم:

لازم نیست تمام این موارد را همین الان رندر کنید. کارهای مربوط به محتوایی را که کاربر هنوز نمی‌تواند ببیند، رد کنید.

CSS دارای ویژگی‌ای است که می‌تواند به ما کمک کند دقیقاً همین کار را در یک خط انجام دهیم:

    .card {
  content-visibility: auto;
}

  

که به طور طبیعی باعث شد کنجکاو شوم که این کار واقعاً چقدر می‌تواند تفاوت ایجاد کند.

بنابراین به جای اکتفا به مستندات، صفحه‌ای با ۱۵۰ کارت پر از محتوا ساختم، ابزار توسعه‌دهنده کروم (Chrome DevTools) را باز کردم و آن را اندازه‌گیری نمودم.

نتیجه بسیار بزرگ‌تر از چیزی بود که انتظار داشتم. اما مشکل دیگری را نیز ایجاد کرد.

بیایید با این موضوع شروع کنیم که content-visibility در واقع از مرورگر چه می‌خواهد.

آنچه در این مقاله بررسی خواهیم کرد:

  • ویژگی content-visibility: auto در واقع چه کاری انجام می‌دهد؟
  • من صفحه‌ای با ۱۵۰ کارت ساختم
  • ما کارهای رندرینگ را ذخیره کردیم. اکنون طرح‌بندی (Layout) مشکلی دارد.
  • صبر کنید، آیا این همان بارگذاری تنبل (Lazy Loading) نیست؟
  • اما وضعیت دسترسی‌پذیری (Accessibility) چه می‌شود؟
  • بنابراین، چه زمانی استفاده از content-visibility واقعاً ارزش دارد؟

پیش‌نیازها

برای دنبال کردن این مقاله، باید موارد زیر را داشته باشید:

  • درک پایه‌ای از HTML و CSS
  • یک مرورگر مدرن مانند کروم
  • آشنایی پایه با Chrome DevTools

شما به هیچ دانش فریم‌ورکی نیاز ندارید. این آزمایش از HTML، CSS و JavaScript ساده استفاده می‌کند تا بتوانیم به‌طور خاص روی رفتار رندرینگ مرورگر تمرکز کنیم.

ویژگی content-visibility: auto در واقع چه کاری انجام می‌دهد؟

ویژگی content-visibility کنترل می‌کند که آیا یک عنصر محتوای خود را رندر کند یا خیر.

برای این آزمایش، ما به یک مقدار علاقه‌مند هستیم:

    .card {
  content-visibility: auto;
}

  

با مقدار auto، مرورگر می‌تواند کارهای رندرینگ محتوای یک عنصر را زمانی که آن عنصر در حال حاضر برای کاربر مرتبط نیست (مانند زمانی که بسیار خارج از محدوده دید قرار دارد) رد کند.

نکته مهم این است که ما در مورد رندرینگ صحبت می‌کنیم.

این عنصر از DOM حذف نشده است. و content-visibility در درجه اول به مرورگر نمی‌گوید که منابع آن را دانلود نکند.

ما به مرورگر فرصتی می‌دهیم تا از انجام کارهای رندرینگی که هنوز مفید نیستند، اجتناب کند.

این کار از طریق محدودسازی CSS (CSS containment) انجام می‌شود. همان‌طور که راهنمای web.dev توضیح می‌دهد، content-visibility: auto محدودسازی طرح‌بندی، استایل و ترسیم (layout, style, and paint containment) را اعمال می‌کند. هنگامی که محتوا برای کاربر مرتبط نیست، مرورگر می‌تواند کارهای بیشتری را برای آن زیردرخت (subtree) رد کند.

بنابراین بدون content-visibility، مرورگر ممکن است همچنان کارهای رندرینگ را برای محتوایی که خیلی پایین‌تر از محدوده دید قرار دارد انجام دهد. با وجود آن، می‌توان برخی از این کارها را تا زمانی که محتوا مرتبط شود، به تعویق انداخت.

به کلمه «می‌تواند» (can) توجه کنید.

ویژگی content-visibility: auto تضمین نمی‌کند که رندرینگ هر عنصر خارج از محدوده دید همیشه رد شود. مرورگر تعیین می‌کند که آیا محتوا برای کاربر مرتبط است و آیا می‌توان رندرینگ آن را رد کرد یا خیر.

این به نظر مفید می‌آید. اما چقدر مفید؟

وقت اندازه‌گیری است.

من صفحه‌ای با ۱۵۰ کارت ساختم

من نمی‌خواستم این را روی یک دموی کوچک آزمایش کنم که در آن تفاوت ممکن است در نویز اندازه‌گیری گم شود.

بنابراین من عمداً صفحه را کمی خنده‌دار و اغراق‌آمیز طراحی کردم. این صفحه شامل ۱۵۰ کارت پر از محتوا است.

هر کارت دارای موارد زیر است:

  • یک جایگاه (placeholder) تصویر با اندازه ثابت
  • یک عنوان و برچسب‌ها
  • هشت پاراگراف
  • ده آیتم مرتبط

عدد ۱۵۰ عدد خاصی نیست.

یک صفحه صرفاً به این دلیل که از آستانه خاصی در تعداد عناصر عبور می‌کند، ناگهان به گزینه مناسبی برای content-visibility تبدیل نمی‌شود.

برای مثال، ۱۵۰ عنصر ساده <div> ممکن است کار سنگین بسیار کمی برای رد شدن به مرورگر بدهند.

اما ۱۵۰ بخش حاوی طرح‌بندی تو‌در‌تو، متن، فهرست‌ها، تصاویر و سایر کارهای رندرینگ، فرصت بسیار بهتری ایجاد می‌کنند.

برای این آزمایش، دقیقا همین را می‌خواستم.

من همچنین به جای ری‌اکت (React) یا سایر فریمورک‌ها، از HTML، CSS و جاوا اسکریپت خالص استفاده کردم.

این کار عمدی بود.

اگر قرار است یک بهینه‌سازی رندرing در CSS را آزمایش کنیم، اضافه کردن اجرای فریمورک متغیر دیگری به ما می‌دهد که به آن نیازی نداریم.

این هم کُد جاوا اسکریپتی که کارت‌ها را تولید می‌کند:

    const CARD_COUNT = 150;
const PARAGRAPHS_PER_CARD = 8;
const RELATED_ITEMS_PER_CARD = 10;

const cards = [];

for (let i = 1; i <= CARD_COUNT; i++) {
  cards.push(`
    <article class="card">
      <div class="card-image-placeholder"></div>

      <h2>Product ${i}</h2>

      ${Array.from(
        { length: PARAGRAPHS_PER_CARD },
        (_, index) => `
          <p>
            Product ${i}, paragraph ${index + 1}.
            This is sample content used to make
            each card more expensive to render.
          </p>
        `
      ).join("")}

      <ul>
        ${Array.from(
          { length: RELATED_ITEMS_PER_CARD },
          (_, index) => `
            <li>Related item ${index + 1}</li>
          `
        ).join("")}
      </ul>
    </article>
  `);
}

document.querySelector("#feed").innerHTML = cards.join("");

  

من به استفاده از تصاویر واقعی فکر کردم، اما این کار آزمایش را پیچیده‌تر می‌کرد.

تاخیر شبکه، کش کردن (caching) و رمزگشایی تصویر همگی می‌توانند روی آنچه می‌بینیم تأثیر بگذارند.

بنابراین هر کارت به جای آن از یک جایگاه (placeholder) مبتنی بر CSS استفاده می‌کند:

    .card-image-placeholder {
  height: 320px;
  background: linear-gradient(
    135deg,
    #e5e7eb,
    #f3f4f6
  );
}

  

برای هر پیکربندی، محیط مرورگر و اندازه ویوپورت را ثابت نگه داشتم و در طول ضبط بارگذاری اولیه (initial-load)، اسکرول نکردم.

همچنین به جای انتخاب زیباترین نتیجه، آزمایش‌ها را تکرار کردم.

اگر می‌خواهید این آزمایش را بازسازی کنید، من نمونه کامل را در گیت‌هاب در اینجا منتشر کرده‌ام.

این مخزن شامل همان صفحه آزمایشی و پیکربندی‌های استفاده‌شده برای اندازه‌گیری‌های زیر است، بنابراین می‌توانید خودتان آزمایش را اجرا کنید و نتایج را روی مرورگر و دستگاه خود مقایسه کنید.

اکنون چیزی برای اندازه‌گیری داریم.

ابتدا، وضعیت پایه (Baseline)

قبل از اضافه کردن content-visibility، با استفاده از پنل Performance در ابزارهای توسعه‌دهنده کروم (Chrome DevTools)، سه بار از صفحه رکورد گرفتم.

فعالیت رندرینگ گزارش‌شده در رکورد Performance به این صورت بود:

اجرا رندرینگ
1 ۳۹ میلی‌ثانیه
2 ۴۴ میلی‌ثانیه
3 ۴۲ میلی‌ثانیه
میانه (Median) ۴۲ میلی‌ثانیه

من به جای انتخاب سریع‌ترین اجرا، از مقدار میانه استفاده کردم.

یک نکته مهم وجود دارد که باید روشن شود. این اعداد نشان‌دهنده فعالیت رندرینگ گزارش‌شده در رکورد Performance ابزارهای توسعه‌دهنده هستند.

این‌ها کل زمان بارگذاری صفحه، یک معیار حیاتی وب (Core Web Vital) یا اندازه‌گیری مستقیمی از کارایی درک‌شده توسط کاربر نیستند.

ابزارهای توسعه‌دهنده کروم، رندرینگ را به عنوان یکی از دسته‌ها در تفکیک فعالیت‌های یک رکورد Performance گزارش می‌دهند، و به همین دلیل است که من به جای گفتن اینکه صفحه «در ۴۲ میلی‌ثانیه رندر شد»، به‌طور خاص به «فعالیت رندرینگ» اشاره می‌کنم.

بنابراین وضعیت پایه ما این بود:

فعالیت میانه‌ی رندرینگ: ۴۲ میلی‌ثانیه
Chrome DevTools Performance recording showing Rendering activity for the baseline test without content-visibility.

یک رکورد Performance از وضعیت پایه. مقدار میانه‌ی ۴۲ میلی‌ثانیه در بالا از سه اجرای مجزا محاسبه شده است.

سپس دقیقاً یک چیز را تغییر دادم:

    .card {
  content-visibility: auto;
}

  

و آزمایش را دوباره اجرا کردم.

اجرا رندر کردن
1 20 ms
2 21 ms
3 20 ms
میانه 20 ms

بسیار خب. این اصلاً ناچیز نیست.

ما از این وضع رسیدیم به:

    42 ms → 20 ms

Or: 

(42 - 20) / 42 × 100 ≈ 52%

  

در این آزمایش، افزودن content-visibility: auto با کاهش تقریبی ۵۲ درصدی فعالیت Rendering که توسط ابزارهای توسعه‌دهنده کروم (Chrome DevTools) گزارش شده بود، همراه شد.

Chrome DevTools Performance recording after applying content-visibility: auto to the cards.

اما باید در مورد آن عدد احتیاط کنیم.

این به این معنا نیست که content-visibility وب‌سایت‌ها را ۵۲ درصد سریع‌تر می‌کند. حتی به این معنا نیست که کل صفحه ۵۲ درصد سریع‌تر بارگذاری شده است.

ما یک دسته‌بندی از فعالیت‌ها را در داخل Chrome DevTools با استفاده از یک صفحه عمدتاً حجیم در یک محیط آزمایشی اندازه‌گیری کردیم.

نتیجه به مواردی بستگی خواهد داشت مانند:

  • چه مقدار محتوا در پایین صفحه (خارج از دید اولیه) دارید
  • رندر کردن آن محتوا چقدر هزینه و پردازش دارد
  • مرورگر
  • دستگاه
  • محدوده دید (Viewport)
  • ساختار صفحه

آزمایش ما اساساً به گونه‌ای طراحی شده بود که حجم زیادی از کار را برای رد شدن (skip کردن) به content-visibility بدهد.

بنابراین نتیجه مفید این نیست که:

«content-visibility وب‌سایت‌ها را ۵۲ درصد سریع‌تر می‌کند.»

بلکه این است:

در صفحات دارای محتوای قابل توجه در خارج از صفحه (off-screen)، اجازه دادن به مرورگر برای رد کردن کارهای رندر غیرضروری می‌تواند بهبود قابل اندازه‌گیری ایجاد کند.
Diagram showing content-visibility rendering visible cards inside the viewport while allowing rendering work for off-screen cards to be skipped.

وب‌سایت web.dev نیز ایده مشابهی را با نسخه نمایشی پرمحتوای خود نشان داده و در آنجا نیز بهبود چشمگیری را گزارش کرده است.

اما عدد آن‌ها متعلق به آزمایش خودشان است و عدد ما متعلق به آزمایش خودمان.

هیچ‌کدام درصدی نیستند که بتوانید بدون اندازه‌گیری، آن را در اپلیکیشن خود کپی کنید.

اما آزمایش ما هنوز تمام نشده است. زیرا پس از شروع اسکرول کردن، مشکل دیگری ظاهر شد.

کار رندر را ذخیره کردیم. اکنون طرح‌بندی (Layout) مشکل دارد.

به آنچه تازه به مرورگر گفتیم فکر کنید: یک کارت خیلی پایین‌تر از محدوده دید قرار دارد، بنابراین محتوای آن را می‌توان نادیده گرفت.

بسیار عالی. اما صفحه همچنان به یک طرح‌بندی (Layout) نیاز دارد.

بنابراین این سوال عجیب مطرح می‌شود: قبل از اینکه مرورگر اندازه رندر شده‌ی عادی کارت را بداند، یک کارت خارج از صفحه چقدر فضا باید اشغال کند؟

اگر هندسه اولیه مرورگر با اندازه واقعی کارت مطابقت نداشته باشد، هنگامی که کارت مرتبط می‌شود و محتوای آن رندر می‌گردد، طرح‌بندی می‌تواند تنظیم شود.

اینجاست که ویژگی contain-intrinsic-size وارد عمل می‌شود.

ما می‌توانیم یک اندازه ذاتی جایگزین (fallback) به مرورگر بدهیم:

    .card {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}

  

مقدار 900px به مرورگر یک اندازه ذاتی جایگزین می‌دهد تا زمانی که محتوا نادیده گرفته می‌شود و هیچ اندازه رندر شده‌ی ذخیره‌شده‌ای در دسترس نیست، از آن استفاده کند.

اما بخش auto این موضوع را جذاب‌تر می‌کند.

تصور کنید کارت هنوز به‌طور عادی رندر نشده است. مرورگر اندازه قبلی برای استفاده مجدد ندارد، بنابراین مقدار ۹۰۰ پیکسلی ما می‌تواند به عنوان مقدار پیش‌فرض جایگزین (fallback) عمل کند.

بعداً، کارت به اندازه کافی به محدوده دید (viewport) نزدیک شده و به‌طور عادی رندر می‌شود. اکنون مرورگر اندازه رندرشابه‌شده واقعی آن را مشاهده کرده است.

اگر آن کارت دوباره قابل پرش (skippable) شود، مرورگر می‌تواند به جای بازگشت به مقدار ۹۰۰ پیکسل، از اندازه به خاطر سپرده‌شده استفاده مجدد کند.

بنابراین:

    contain-intrinsic-size: auto 900px;

  

به این معنا نیست که مرورگر به طریقی می‌داند کارت ۹۰۰ پیکسل ارتفاع دارد.

بلکه به این معناست:

Flowchart showing how contain-intrinsic-size uses a remembered rendered size when available, or a 900px fallback when no remembered size exists.

این ویژگی در کنار content-visibility نیز مفید است.

اگر محتوا را نادیده بگیریم، پیش از رندر شدن آن محتوا، همچنان به هندسه معقولی برای صفحه نیاز داریم.

پس مقدار پیش‌فرض (Fallback) چه باید باشد؟

اولین سوال من این بود که آیا انتخاب یک مقدار پیش‌فرض کوچک‌تر یا بزرگ‌تر تأثیر محسوسی روی اندازه گیری اولیه رندرینگ خواهد داشت یا خیر.

بنابراین سه مقدار را امتحان کردم:

مقدار پیش‌فرض (Fallback) رندرینگ (Rendering)
100px 12 ms
900px 10 ms
2000px 11 ms

این نتایج بسیار به هم نزدیک هستند.

در این مقیاس، تفاوت‌ها آنقدر کوچک هستند که نمی‌توانم آن‌ها را به عنوان مدرکی مبنی بر اینکه یک مقدار پیش‌فرض سریع‌تر از دیگری است، در نظر بگیرم.

ما نمی‌توانیم به این نتایج نگاه کرده و نتیجه‌گیری کنیم:

«اندازه‌های ذاتی کوچک‌تر سریع‌ترند.»

همچنین نمی‌توانیم نتیجه‌گیری کنیم:

«تخمینی که بیشترین تطابق را با اندازه واقعی دارد، همیشه بهترین عملکرد رندرینگ را خواهد داشت.»

این در واقع وظیفه مقدار پیش‌فرض نیست.

سوال مفیدتر این است که چه اتفاقی برای لایه بندی (layout) می‌افتد.

اگر مقدار پیش‌فرض شما ۱۰۰ پیکسل باشد، اما مشخص شود که کارت واقعی بسیار بلندتر است، ممکن است صفحه هنگام رندر شدن محتوا نیاز داشته باشد هندسه خود را تنظیم کند.

عکس این موضوع نیز می‌تواند رخ دهد اگر مقدار پیش‌فرض شما بسیار بزرگ‌تر از محتوای واقعی باشد.

بنابراین شما به یک تقریب معقول نیاز دارید، نه یک عدد جادویی برای عملکرد.

اما حین آزمایش این موضوع، متوجه چیزی شدم که انتظارش را نداشتم.

فقط با

    .card {
  content-visibility: auto;
}

  

من بعداً سه اندازه گیری انجام دادم:

    20 ms
21 ms
20 ms

Median: 20 ms

  

سپس این را اضافه کردم:

    .card {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}

  

و این نتیجه را گرفتم:

    10 ms
9 ms
12 ms

Median: 10 ms

  

بنابراین بله، در این آزمایش خاص، افزودن مقدار پیش‌فرض صریح با کاهش دیگری در فعالیت رندرینگ ابزار توسعه‌دهنده کروم (Chrome DevTools) همراه بود.

نتیجه‌گیری وسوسه‌انگیز:

    contain-intrinsic-size = 2× faster

  

خیر. اندازه‌گیری ما به ما می‌گوید که در این آزمایش چه اتفاقی افتاده است.

این آزمایش ویژگی عملکردی کلی برای contain-intrinsic-size را اثبات نمی‌کند.

وظیفه آن فراهم کردن هندسه ذاتی مفیدی است که محدودسازی اندازه (size containment) اعمال می‌شود، از جمله ارائه یک مقدار پیش‌فرض زمانی که هیچ اندازه یادآوری‌شده‌ای از رندر طبیعی در دسترس نباشد.

دلیل دیگری هم وجود دارد که باید در مورد این اعداد احتیاط کرد. مقایسه مبنای اصلی از سه اجرا استفاده کرد، در حالی که این اندازه‌گیری‌های اکتشافی بعدی نیز از سه اجرا استفاده کرده‌اند.

این کار برای چیزی که هنگام آزمایش متوجه شدم مشکلی ندارد. این همان متدولوژی کنترل‌شده‌ای نیست که بخواهم از آن استفاده کنم تا ادعا کنم یک پیکربندی به‌طور کلی سریع‌تر از دیگری است.

بنابراین، نتیجه ۱۰ میلی‌ثانیه‌ای دقیقاً همان چیزی که هست باقی می‌ماند: یک مشاهده جالب از این آزمایش؛ نه یک تضمین از سوی مرورگر.

آیا صرفاً کار را به بخش اسکرول منتقل کرده‌ایم؟

سؤال دیگری وجود دارد که بنچمارک بارگذاری اولیه به آن پاسخ نمی‌دهد.

اگر کارهای مربوط به کارت‌های خارج از صفحه را نادیده بگیریم، برخی از آن کارت‌ها در نهایت با اسکرول کردن کاربر اهمیت پیدا خواهند کرد.

این کار به طور جادویی ناپدید نشده است. مقداری از آن تا زمانی که مرورگر تشخیص دهد محتوا مرتبط است، به تعویق افتاده است.

بنابراین، آیا کل تجربه را بهبود بخشیده‌ایم، یا صرفاً مقداری از کار را به جای دیگری منتقل کرده‌ایم؟

من در این آزمایش بنچمارکی ندارم که به این موضوع پاسخ دهد.

من یک تست اسکرول کنترل‌شده ثبت نکردم، بنابراین قصد ندارم آنچه را که هنگام اسکرول دستی دیدem به ادعای عملکردی دیگری تبدیل کنم.

یک آزمایش جداگانه باید به بررسی اسکرول، کارت‌هایی که مرتبط می‌شوند، تغییرات لایه‌ها (layout shifts) و رفتار فریم‌ها هنگام حرکت در صفحه بپردازد.

در حال حاضر، اندازه‌گیری ما چیز بسیار محدودتری را به ما می‌گوید:

ویژگی content-visibility: auto فعالیت رندرینگ اولیه را که در این تست خاص اندازه‌گیری شده بود، کاهش داد.

این ویژگی به ما نمی‌گوید که تمام بخش‌های تجربه مرورگری ۵۲ درصد سریع‌تر شده‌اند. و این یک مرز مهم برای اعدادی است که داریم بررسی می‌کنیم.

صبر کنید، آیا این همان بارگذاری تنبل (Lazy Loading) نیست؟

در این مرحله، content-visibility ممکن است به طرز مشکوکی شبیه به بارگذاری تنبل به نظر برسد.

هر دو سعی دارند از کارهای غیرضروری جلوگیری کنند. اما آنها معمولاً از کارهای متفاوتی جلوگیری می‌کنند.

بارگذاری تنبل عمدتاً این سؤال را می‌پرسد:

آیا من همین الان باید این منبع را بارگذاری کنم؟

اما content-visibility سؤال متفاوتی می‌پرسد:

آیا من همین الان باید این محتویات را رندر کنم؟

یک تصویر را در نظر بگیرید:

    <img
  src="/product.jpg"
  loading="lazy"
  alt="Black running shoes"
>

  

بارگذاری تنبل بومی تصاویر می‌تواند بارگذاری آن منبع را تا زمانی که به نیاز به آن نزدیک‌تر شود، به تعویق بیندازد.

اما با وجود:

    .product-card {
  content-visibility: auto;
}

  

عنصر ممکن است از قبل در DOM وجود داشته باشد و منابع آن نیز از قبل بارگذاری شده باشند.

ما از مرورگر می‌پرسیم که آیا اصلاً نیازی به انجام کار رندرینگ برای آن محتویات دارد یا خیر.

بنابراین، این بهینه‌سازی‌ها لزوماً جایگزین یکدیگر نیستند.

شما می‌توانید هر دو را در یک صفحه داشته باشید.

  • یکی می‌تواند به جلوگیری از بارگذاری زودهنگام یک منبع کمک کند.
  • دیگری می‌تواند به جلوگیری از انجام کارهای رندری که در حال حاضر ضروری نیستند کمک کند.
Diagram showing two page performance strategies: lazy loading delays loading resources such as images and JavaScript, while content-visibility can defer layout and painting for off-screen content.

اما وضعیت دسترسی‌پذیری (Accessibility) چه می‌شود؟

نکته جالب توجهی درباره content-visibility: auto وجود دارد که به راحتی ممکن است از قلم بیفتد.

محتوای خارج از صفحه‌ای که رندر آن نادیده گرفته شده است، در DOM باقی می‌ماند و می‌تواند در درخت دسترسی‌پذیری (accessibility tree) نیز در دسترس بماند.

این موضوع برای عملکرد مفید است، اما یک مرز مهم نیز به ما می‌دهد: content-visibility: auto یک بهینه‌سازی رندرینگ است. این یک مکانیزم پنهان‌سازی معنایی نیست.

اگر هدف شما پنهان کردن محتوا از فناوری‌های کمکی (assistive technologies) است، از content-visibility برای این کار استفاده نکنید. به جای آن از HTML، CSS و معناشناسی (semantics) مناسب دسترسی‌پذیری استفاده کنید.

همچنین یک حالت خاص (edge case) وجود دارد که ارزش دانستن دارد. وب‌سایت web.dev اشاره می‌کند که محتوای درون یک زیردرخت نادیده‌گرفته‌شده همچنان می‌تواند در درخت دسترسی‌پذیری ظاهر شود، حتی زمانی که برخی از آن محتواها به‌طور معمول توسط استایل‌هایی مانند display: none یا visibility: hidden پنهان می‌شدند.

بنابراین اگر از content-visibility برای بخش‌های پیچیده یا تعاملی استفاده می‌کنید، به جای این فرض که بهینه‌سازی رندرینگ نمی‌تواند روی دسترسی‌پذیری تأثیر بگذارد، تجربه واقعی کیبورد و فناوری‌های کمکی را تست کنید.

پس، استفاده از content-visibility چه زمانی واقعاً ارزش دارد؟

پس از تمام این اندازه‌گیری‌ها، پاسخ به این اندازه هیجان‌انگیز نیست که بگوییم «افزودن این یک ویژگی CSS می‌تواند وب‌سایت شما را سریع کند».

که احتمالاً نشانه خوبی است.

وقتی صفحه شما حاوی مقدار قابل‌توجهی محتوای سنگین در خارج از محدوده دید (viewport) باشد، ویژگی content-visibility: auto بسیار جذاب می‌شود.

می‌توانید به این موارد فکر کنید:

  • مقالات طولانی یا فیدهای شبکه‌های اجتماعی
  • فهرست‌های بزرگ محصولات
  • صفحات مستندات با بخش‌های فراوان
  • داشبوردهای طولانی
  • بخش‌های پیچیده در پایین صفحه (below-the-fold)

اگر صفحه شما کوچک است و تقریباً همه‌چیز بلافاصله قابل مشاهده است، ممکن است کار رندرینگ زیادی وجود نداشته باشد که بتوان از آن صرف‌نظر کرد.

و قبل از استفاده از آن در محیط عملیاتی (production)، یک سوال عملی باقی می‌ماند: آیا می‌توانید روی پشتیبانی مرورگرها حساب کنید؟

برای مرورگرهای مدرن، پشتیبانی بسیار گسترده است. ویژگی content-visibility بخشی از Baseline 2024 است، بنابراین مگر اینکه پروژه شما نیاز به پشتیبانی از نسخه‌های قدیمی‌تر مرورگر داشته باشد، سازگاری بسیار کمتر از گذشته جای نگرانی دارد.

بنابراین content-visibility چیزی نیست که به آن در هر صفحه‌ای نیاز داشته باشید. اما وقتی یک صفحه حاوی مقدار زیادی محتوای سنگین خارج از صفحه باشد، این ویژگی چیزی ارزشمند به مرورگر می‌دهد: امکان صرف‌نظر کردن از رندر کردن کارهایی که کاربر هنوز نمی‌تواند ببیند.

منابع

  • مستندات MDN برای content-visibility
  • مستندات MDN برای contain-intrinsic-size
  • مقاله web.dev درباره content-visibility

نظر مهندس بهمن آبادی: ویژگی `content-visibility: auto` یک ابزار قدرتمند برای بهینه‌سازی رندرینگ در صفحات سنگین است، اما نباید آن را با لَزی‌لودینگ یا روشی برای پنهان‌سازی محتوا اشتباه گرفت. به عنوان یک مدرس، توصیه می‌کنم همیشه این ویژگی را با `contain-intrinsic-size` همراه کنید تا از پرش‌های ناخواسته لایه‌ها (Layout Shifts) هنگام اسکرول جلوگیری شود؛ با این حال، تاثیر واقعی آن کاملاً به ساختار صفحه شما بستگی دارد و نیاز به تست میدانی دارد.

منبع: https://www.freecodecamp.org/news/css-content-visibility-rendering-performance/